﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Access.PowerTools.AbstractionLayer;
using SMSConsulting.SMSLIB.Utilities;
using Access.PowerTools.Utilities;

namespace Access.PowerTools.Database.Restore.Plug_In
{
    public class RestoreAgent
    {
        private AccessApplication _application;
        public RestoreAgent(AccessApplication application)
        {
            _application = application;
        }

        public void LoadFromText(
             AccessDataBaseObjectTypeEnumeration objectType,
             string objectName,
             string backUpFileFullPath)
        {
            _application.LoadFromText(objectType, objectName, backUpFileFullPath);    
        }

        public EventHandler<RunProgressEventArgs> ReportProgressStatus;


        private List<AccessDatabaseObjectInfo> _objectsTorestore;

        public bool Cancelled { get; private set; }
        public void Cancel()
        {
            Cancelled = true;
        }
        public bool Failed { get; private set; }
        public string ErrorMessage { get; private set; }

        public void RestoreDatabase(
             string backUpFolderPath)
        {
            RestoreDatabase(backUpFolderPath, null, -1);  
        }

        public void RestoreDatabase(
             string backUpFolderPath,
             List<AccessDatabaseObjectInfo> objectsToRestore,
             int accessFormItemSuffixToSet)
        {
            Cancelled = false;
            Failed = false;
            ErrorMessage = "";

            try
            {
                int count = 0;
                int maxCount = 0;

                if (objectsToRestore == null)
                    _objectsTorestore = GetObjectsListFromArchiveFolder(backUpFolderPath);
                else
                    _objectsTorestore = objectsToRestore;

                maxCount = _objectsTorestore.Count;
                foreach (AccessDatabaseObjectInfo objectInfo in _objectsTorestore)
                {
                    System.Threading.Thread.Sleep(10);
                    if (Cancelled) return;

                    count++;
                    string backUpFileFullPath =
                        System.IO.Path.Combine(backUpFolderPath, objectInfo.BackUpFileName);

                    if (ReportProgressStatus != null)
                    {
                        string message = string.Format(
                            "Restoring {0} '{1}' - {2} of {3}...",
                            objectInfo.Type,
                            objectInfo.Name,
                            count, maxCount);
                        RunProgressEventArgs e = new RunProgressEventArgs();
                        e.CurrentCountValue = count;
                        e.MaxCountValue = maxCount;
                        e.Message = message;
                        ReportProgressStatus(this, e);
                    }

                    string tempFileFullPath = null;
                    if (objectInfo.Type == AccessDataBaseObjectTypeEnumeration.Form &&
                        accessFormItemSuffixToSet > 0)
                    {
                        // reset ItemSuffix for access forms
                        tempFileFullPath =
                            System.IO.Path.GetTempFileName();
                        string[] lines = System.IO.File.ReadAllLines(backUpFileFullPath);
                        for (int index = 0; index < lines.Length; index++)
                        {
                            if (lines[index].IndexOf("ItemSuffix", StringComparison.InvariantCultureIgnoreCase) > 0)
                            {
                                string[] values = lines[index].Split(new char[] { '=' });
                                values[1] = accessFormItemSuffixToSet.ToString();
                                lines[index] = string.Join("=", values);
                                break;
                            }
                        }
                        System.IO.File.WriteAllLines(tempFileFullPath, lines);
                    }
                    else tempFileFullPath = backUpFileFullPath;

                    this.LoadFromText(objectInfo.Type, objectInfo.Name, tempFileFullPath);

                }
            }

            catch (Exception ex)
            {
                Failed = true;
                ErrorMessage = ex.Message; 
            }

        }

        private static int comparison(AccessDatabaseObjectInfo o1, AccessDatabaseObjectInfo o2)
        {
            if (o1.Type > o2.Type) return 1;
            if (o1.Type < o2.Type) return -1;
            
            return string.Compare(o1.ObjectTypeAndName, o2.ObjectTypeAndName);
        }

        public static List<AccessDatabaseObjectInfo> GetObjectsListFromArchiveFolder(string archiveFolderPath)
        {
            List<AccessDatabaseObjectInfo> _objects = new List<AccessDatabaseObjectInfo>();

            string[] files = System.IO.Directory.GetFiles(archiveFolderPath);

            foreach (string file in files)
            {
                string fileName = System.IO.Path.GetFileName(file);

                if (fileName.EndsWith("Schema.xml")) continue;
                if (fileName.EndsWith("_TextData.txt")) continue;

                AccessDataBaseObjectTypeEnumeration type =
                    AccessDatabaseObjectInfo.GetObjectTypeByFileName(fileName);
                
                string objectName = Access.PowerTools.Utilities.Strings.DecodeObjectName(    
                    AccessDatabaseObjectInfo.GetObjectNameFromFileName(fileName));

                AccessDatabaseObjectInfo accessObject = new AccessDatabaseObjectInfo(type, objectName);

                _objects.Add(accessObject);
            }

            _objects.Sort(comparison);   
            return _objects;
        }
    }

}
